/*
 * Copyright (c) 2022-2023 cetcclout Co., Ltd All rights reserved.
 * Sensor Adapter is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package com.cetccloud.cimp.adapter.protocol;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.cetccloud.cimp.adapter.cache.CurrentServerCache;
import com.cetccloud.cimp.adapter.datasource.sqldb.service.ModelJoinConfigService;
import com.cetccloud.cimp.adapter.datasource.sqldb.vo.ServerConfig;
import com.cetccloud.cimp.adapter.handler.abstracts.AbstractParserHandler;
import com.cetccloud.cimp.adapter.server.mqtt.publish.MqttPublishClient;
import com.cetccloud.cimp.common.util.R;
import com.cetccloud.cimp.common.util.SensorStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author
 * @apiNote 监听服务配置
 * @date 2023/3/16 15:15
 */
@Service("startOrStopServerService")
public class StartOrStopServerService {

    @Autowired
    ModelJoinConfigService modelJoinConfigService;
    @Autowired
    MqttPublishClient mqttPublishClient;

    /**
     * 通知平台监听服务状态变化信息
     */
    public void changeServerStatus(JSONObject jsonObject){
        JSONObject receiveData = jsonObject.getJSONObject("data");
        Integer status = receiveData.getInt("status");
        String serverId = receiveData.getStr("id");
        if ( 0 == status) {
            ProtocolExecutor protocolExecutor = CurrentServerCache.find(serverId);
            if(ObjectUtil.isNotEmpty(protocolExecutor)){
                protocolExecutor.quit();
                CurrentServerCache.remove (serverId);

                JSONObject returnStatus = new JSONObject();
                returnStatus.putByPath("id", serverId);
                returnStatus.putByPath("status", 0);
                mqttPublishClient.publishServerStatus(JSONUtil.parseObj(R.ok().put("data", returnStatus)));
            }

        }else if(1 == status){
            //启动指定服务
            initAdapterServer(serverId);
        }
    }

    /**
     * 重新加载配置
     */
    public void reloadServerConfig(JSONObject jsonObject){
        JSONObject receiveData = jsonObject.getJSONObject("data");
        String serverId = receiveData.getStr("serverId");
        if(SensorStringUtils.isNotEmpty(serverId)) {
            ProtocolExecutor protocolExecutor = CurrentServerCache.find(serverId);
            if (ObjectUtil.isNotEmpty(protocolExecutor)) {
                List<ServerConfig> serverConfigList =  modelJoinConfigService.selectAllConfig(serverId);
                if(ObjectUtil.isNotEmpty(serverConfigList)) {
                    ServerConfig serverConfig = serverConfigList.get(0);
                    JSONObject config = JSONUtil.parseObj(serverConfig.getParams());
                    for (int i = 0; i < serverConfig.getLinksList().size(); i++) {
                        String s = serverConfig.getLinksList().get(i);
                        //非空加载所有参数
                        if(config.containsKey(s) && SensorStringUtils.isNotEmpty(config.getStr(s))){
                            Object handler = protocolExecutor.getDefaultDataChain().getHandlerMap().get(serverConfig.getDoLinkList().get(i));
//                            if(handler instanceof AbstractProtocolEndpoint){
//                                ((AbstractProtocolEndpoint)handler).init(config.getStr(s));
//                            }
//                            else
//                            if(handler instanceof AbstractAuthHandler){
//                                ((AbstractAuthHandler)handler).init(config.getStr(s));
//                            }
//                            else
                            if(handler instanceof AbstractParserHandler){
                                ((AbstractParserHandler)handler).init(config.getStr(s));
                            }
//                            else
//                            if(handler instanceof AbstractCheckHandler){
//                                ((AbstractCheckHandler)handler).init(config.getStr(s));
//                            }
                        }

                    }
                }

            }
        }
    }

    /**
     * 初始化需要启动的服务配置
     */
    public void initAdapterServer(String serverId) {
        try {
            List<ServerConfig> serverConfigList =  modelJoinConfigService.selectAllConfig(serverId);
            if(ObjectUtil.isNotEmpty(serverConfigList)) {
                for (ServerConfig serverConfig : serverConfigList) {
                    ProtocolExecutor protocolExecutor = null;

                    JSONObject jsonObject = new JSONObject();
                    jsonObject.putByPath("id", serverConfig.getId());
                    try {
                        protocolExecutor = ProtocolExecutor.init(
                                serverConfig.getServerType(),
                                serverConfig);

                        if (ObjectUtil.isNotEmpty(protocolExecutor)) {
                            CurrentServerCache.add(serverConfig.getId().toString(), protocolExecutor);
                            //服务启动成功发送信息给平台
                            jsonObject.putByPath("status", 1);
                        } else {
                            //服务启动失败发送信息给平台
                            jsonObject.putByPath("status", 0);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        //服务启动失败发送信息给平台
                        jsonObject.putByPath("status", 0);
                    }

                    mqttPublishClient.publishServerStatus(JSONUtil.parseObj(R.ok().put("data", jsonObject)));
                }
            }else {
                if(ObjectUtil.isNotEmpty(serverId)) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.putByPath("id", serverId);
                    jsonObject.putByPath("status", 0);
                    mqttPublishClient.publishServerStatus(JSONUtil.parseObj(R.ok().put("data", jsonObject)));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            if(ObjectUtil.isNotEmpty(serverId)) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.putByPath("id", serverId);
                jsonObject.putByPath("status", 0);
                mqttPublishClient.publishServerStatus(JSONUtil.parseObj(R.ok().put("data", jsonObject)));
            }
        }
    }
}
